package com.maxmlr.concurrent.queue;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName DelayQueueTest
 * @Description 无界阻塞队列，只有在延迟期满时，才能从中提取元素-定时作务
 * @Author maxiao
 * @Date 2020/2/25 下午4:00
 * @Version V1.0
 */
public class DelayQueueTest {


    public static void main(String[] args) {
        BlockingQueue<MyTast> tasts = new DelayQueue();

        long l = System.currentTimeMillis();
        MyTast tast1 = new MyTast("task1", l + 1000);
        MyTast tast2 = new MyTast("task2", l + 2000);
        MyTast tast3 = new MyTast("task3", l + 2000);
        MyTast tast4 = new MyTast("task4", l + 3000);
        MyTast tast5 = new MyTast("task5", l + 4000);

        tasts.add(tast1);
        tasts.add(tast5);
        tasts.add(tast3);
        tasts.add(tast2);
        tasts.add(tast4);

        System.out.println(tasts);

        new Thread(() -> {
            System.out.println("开始处理--");
            try {
                while (!tasts.isEmpty()) {
                    MyTast take = tasts.take();
                    System.out.println(take.name + "---" + take.runningTime);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }

    static class MyTast implements Delayed {


        String name;
        long runningTime;

        public MyTast(String name, long runningTime) {
            this.name = name;
            this.runningTime = runningTime;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(runningTime - System
                    .currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        /**
         * 这里根据取消时间来比较，如果取消时间小的，就会优先被队列提取出来
         *
         * @param o
         * @return
         */
        @Override
        public int compareTo(Delayed o) {
            if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
                return 1;
            } else if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
                return -1;
            } else {
                return 0;
            }
        }


        @Override
        public String toString() {
            return name + ":" + runningTime;
        }
    }
}
